package com.guoranhao.admin.web.interceptor;

import com.guoranhao.admin.constants.ApiConstants;
import com.guoranhao.admin.web.filter.HttpServletRequestDecorator;
import com.guoranhao.admin.web.utils.IpUtil;
import com.guoranhao.tool.utils.JsonUtil;
import com.guoranhao.tool.utils.LogUtil;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

/**
 * Description: HHTP接口响应时间拦截器
 * Copyright (c) Department of Research and Development/Beijing
 * All Rights Reserved.
 *
 * @version 1.0 2019-02-11 10:02 by 郝浩天（haoht@cloud-young.com）创建
 */
@Component
public class LatencyInterceptor extends HandlerInterceptorAdapter {
	
	private static final Logger logger = LoggerFactory.getLogger(LatencyInterceptor.class);

	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
		long startTime = System.currentTimeMillis();  
        request.setAttribute("start_time", startTime);  
        return true;
	}

	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
		long startTime = (Long) request.getAttribute("start_time");
		long endTime = System.currentTimeMillis();
		long executeTime = endTime - startTime;

		//Header Data
		Map<String, Object> headMap = new HashMap<>();
		Enumeration<String> headerNames = request.getHeaderNames();
		while (headerNames.hasMoreElements()) {
			String headerKey = headerNames.nextElement();
			String headerValue = request.getHeader(headerKey);
			if (StringUtils.isNotBlank(headerKey) && StringUtils.isNotBlank(headerValue)) {
				headMap.put(headerKey, headerValue);
			}
		}
		//Parameter Data
		Map<String, String[]> paramsMap = request.getParameterMap();

		//Request Body Parameter
		ServletRequest requestWrapper = new HttpServletRequestDecorator(request);
		BufferedReader br = requestWrapper.getReader();
		String inputLine;
		StringBuilder bodyParamJson = new StringBuilder();
		try {
			while ((inputLine = br.readLine()) != null) {
				bodyParamJson.append(inputLine);
			}
		} catch (IOException e) {
			LogUtil.error(logger, e, "【postHandle】error ");
		} finally {
			br.close();
		}

		//Ip Address
		String requestIp = IpUtil.getRealIp(request);
		//Ip Address
		String userAgent = request.getHeader(ApiConstants.HTTP_HEADER_USER_AGENT);

		//log print
		LogUtil.info(logger, "Http Request URI:{0} Response Time:{1}ms \n " +
						"Http Request Ip Address:{2} \n " +
						"Http Request Header Data:{3} \n " +
						"Http Request Parameter Data:{4} \n " +
						"Http Request Body Data:{5} \n " +
						"Http Request Body Data:{6}",
				request.getRequestURI(), executeTime, requestIp, JsonUtil.Object2Json(headMap), JsonUtil.Object2Json(paramsMap), bodyParamJson.toString(),userAgent);
	}

	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
		// TODO Auto-generated method stub
	}

}
